package org.project.d.network.online;


import lombok.extern.slf4j.Slf4j;
import org.project.d.network.Connection;
import org.project.d.network.TcpConnectionManager;

import java.util.Set;

/**
 * @author lin
 * @version V1.0
 * @description
 * @date 2020/10/16 3:47 下午
 */
@Slf4j
public class OnlineManagerImpl implements UserStateManager {
    RemoteOnlineManager remoteOnlineManager=new DefRemoteOnlineManager();
    LocalOnlineManager localOnlineManager=new MapLocalOnlineManager();
    //    todo 本地链接不存在的时候通知其他服务器该用户下线？暂时不通知，因为下线上线主要维护于本机
    public OnlineManagerImpl(RemoteOnlineManager remoteOnlineManager, LocalOnlineManager localOnlineManager) {
        if (remoteOnlineManager!=null)
        this.remoteOnlineManager = remoteOnlineManager;
        if (localOnlineManager!=null)
        this.localOnlineManager = localOnlineManager;
    }

    @Override
    public boolean online(OnlineInfo onlineInfo) {
        if (remoteOnlineManager.online(onlineInfo)) {
            localOnlineManager.online(onlineInfo);
            return true;
        }
        return false;
    }

    @Override
    public boolean offline(OnlineInfo onlineInfo) {
        OnlineInfo selectOnlineInfo = null;
        if (onlineInfo.getUserId() != null) {
            selectOnlineInfo = localOnlineManager.selectOnlineInfo(onlineInfo.getUserId());
        } else if (onlineInfo.getClineAddress() == null) {
            selectOnlineInfo = localOnlineManager.selectOnlineInfoByIp(onlineInfo.getClineAddress());
        }
        if (selectOnlineInfo == null) {
            return false;
        }
        if (remoteOnlineManager.offline(selectOnlineInfo)) {
            localOnlineManager.offline(selectOnlineInfo);
//          下线后关闭客户端链接
            Connection connection = TcpConnectionManager.get(onlineInfo.getClineAddress());
            if (connection != null) {
                connection.close();
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean kickline(OnlineInfo onlineInfo) {
        OnlineInfo selectOnlineInfo = null;
        if (onlineInfo.getUserId() != null) {
            selectOnlineInfo = localOnlineManager.selectOnlineInfo(onlineInfo.getUserId().toString());
        } else if (onlineInfo.getClineAddress() == null) {
            selectOnlineInfo = localOnlineManager.selectOnlineInfoByIp(onlineInfo.getClineAddress());
        }
        if (selectOnlineInfo == null) {
            return false;
        }
        if (remoteOnlineManager.kickline(onlineInfo)) {
//          踢人后关闭客户端链接
            localOnlineManager.kickline(onlineInfo);
            Connection connection = TcpConnectionManager.get(onlineInfo.getClineAddress());
            if (connection != null) {
                connection.close();
            }
            return true;
        }
        return false;
    }

    @Override
    public OnlineInfo selectOnlineInfo(String id) {
        OnlineInfo onlineInfo = localOnlineManager.selectOnlineInfo(id);
        if (onlineInfo == null) {
            return remoteOnlineManager.selectOnlineInfo(id);
        }
        return onlineInfo;
    }

    @Override
    public boolean update(OnlineInfo onlineInfo) {
        if (localOnlineManager.selectOnlineInfo(onlineInfo.getUserId().toString()) == null) {
            return false;
        }
        if (remoteOnlineManager.update(onlineInfo)) {
            localOnlineManager.update(onlineInfo);
        }
        return true;
    }

    @Override
    public void keepLive(String id) {
        remoteOnlineManager.keepLive(id);
        localOnlineManager.keepLive(id);
    }

    @Override
    public void offlineAll() {
        log.info("clear OnlineManager .... ");
        Set<String> cacheKeys = localOnlineManager.getCacheKeys();
        remoteOnlineManager.offline(cacheKeys);
        localOnlineManager.offlineAll();
        log.info("clear OnlineManager ok ");
    }

    @Override
    public Connection getConnection(String id) {
        OnlineInfo onlineInfo = selectOnlineInfo(id);
        if (onlineInfo!=null){
            return TcpConnectionManager.get(onlineInfo.getClineAddress());
        }
        return null;
    }

    @Override
    public void keepLiveByIp(String ip) {
        String id = localOnlineManager.getId(ip);
        localOnlineManager.keepLive(id);
        remoteOnlineManager.keepLive(id);
    }
}
